VK Cup 2016 - Round 1 D. Bear and Polynomials(哈希)
题意:
$N\le 2\times 10^5,给定一个N次多项式,即P(x)=\sum_{i=0}^N a_i\cdot x^i$
$已经P(2)\neq 0,现要改变其中一个系数a_i,使得P’(2)=0$
$求方法数$
分析:
$由于N非常大,所以直接算是不行的$
$我们可以通过对素数取模来哈希这个结果,这个素数一定要比max\{a_i\}大$
$取2个素数,之后枚举每个系数,算出答案,比较是否相等即可,同时别忘记负数答案了$
$各种取模,注意不要模出负数了$
$时间复杂度O(n)$
代码:
//
// Created by TaoSama on 2016-03-29
// Copyright (c) 2016 TaoSama. All rights reserved.
//
#pragma comment(linker, "/STACK:102400000,102400000")
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>
using namespace std;
#define pr(x) cout << #x << " = " << x << " "
#define prln(x) cout << #x << " = " << x << endl
const int N = 2e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7;
int n, k;
int a[N];
typedef long long LL;
LL ksm(LL x, LL n, LL MOD) {
LL ret = 1;
for(; n; n >>= 1) {
if(n & 1) ret = ret * x % MOD;
x = x * x % MOD;
}
return ret;
}
int main() {
#ifdef LOCAL
freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin);
// freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout);
#endif
ios_base::sync_with_stdio(0);
scanf("%d%d", &n, &k);
LL sum[2] = {}, mod[2] = {MOD, MOD + 2};
LL power[2] = {1, 1}, base[2] = {2, 2};
for(int i = 0; i <= n; ++i) {
scanf("%d", a + i);
for(int j = 0; j < 2; ++j) {
sum[j] = (sum[j] + a[i] * power[j] % mod[j]) % mod[j];
sum[j] = (sum[j] + mod[j]) % mod[j];
power[j] = power[j] * base[j] % mod[j];
}
}
int ans = 0;
for(int i = 0; i < 2; ++i) power[i] = 1, base[i] = ksm(2, mod[i] - 2, mod[i]);
for(int i = 0; i <= n; ++i) {
LL delta[2];
for(int j = 0; j < 2; ++j) {
delta[j] = (a[i] - sum[j] * power[j] % mod[j]) % mod[j];
delta[j] = (delta[j] + mod[j]) % mod[j];
power[j] = power[j] * base[j] % mod[j];
}
LL cof = INF;
if(delta[0] == delta[1]) cof = delta[0];
if(delta[0] - mod[0] == delta[1] - mod[1]) cof = delta[0] - mod[0];
if(abs(cof) > k || i == n && cof == 0) continue;
++ans;
}
printf("%d\n", ans);
return 0;
}